package app.action;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

import javax.swing.JOptionPane;

import app.ui.MakeDataFileUi;

public class ExportQuesstionTextDatHelper {
	private final String author = "fatm_1990@yahoo.com";
	private final String ansLetStr = "ABCD";
	private final String pathFileMp3 = "pathFileMp3";
	private final String amountOfQuestion = "AmountOfQuestion";
	private final String questionStr = "q";
	private final String answerStr = "ANS";
	private final String tapScr = "TapScr";

	private int amtQue = 0;
	private int tmpIndexTS = 0;
	private int tmpIndexAN = 0;
	private int tmpIndexQU = 0;
	private Properties queProp = null;
	private String saveToPath;
	private boolean enalbe = false;

	private MakeDataFileUi comp; // this component is for locate the message box

	public String[] answersVal = new String[4];
	public String questionVal;

	public ExportQuesstionTextDatHelper(MakeDataFileUi comp, Properties queProp) {
		this.comp = comp;
		this.queProp = queProp;
	}

	public void saveFileData(String fileName, String pathFileMp3) {
		String fName = null;
		String extension = ".dat";
		fileName = fileName.replace(extension, "");

		if (this.saveToPath == null || saveToPath.length() < 1) {
			String message = "save path = null";
			JOptionPane.showMessageDialog(comp, message);
			return;
		} else if (pathFileMp3 == null || pathFileMp3.trim().length() < 1) {
			String message = "pathFileMp3 = null";
			JOptionPane.showMessageDialog(comp, message);
			return;
		}
		// copy mp3 file to the target
		fName = fileName + "." + SelectMP3FileAction.extension[0];
		File source = new File(pathFileMp3);
		File target = new File(this.saveToPath + "/" + fName);
		FileUtilities fileUtilities = new FileUtilities();
		if (fileUtilities.getExtension(source).equals(SelectMP3FileAction.extension[0])) {
			fileUtilities.copyFile(source, target);
		}
		try {
			writeHeader(fName);
		} catch (Exception e) {
			JOptionPane.showMessageDialog(comp, e.getMessage());
		}

		if (amtQue == 0 || !enalbe) {
			String message = "amtQue = " + amtQue + "\n" + "enalbe = " + enalbe;
			JOptionPane.showMessageDialog(comp, message);
			return;
		}

		fName = this.saveToPath + "/" + fileName + extension;
		try {
			FileOutputStream out = new FileOutputStream(new File(fName));
			queProp.store(out, author);
			this.enalbe = false;
		} catch (FileNotFoundException e) {
			JOptionPane.showMessageDialog(comp, e.getMessage());
		} catch (IOException e) {
			JOptionPane.showMessageDialog(comp, e.getMessage());
		}
	}

	public int writeTapeScrip(String ts, int index) throws Exception {
		if (ts == null || (ts.length() < 1)) {
			throw new Exception("Tape script is not acceptable!");
		}

		if (checkValidIndex(index)) {
			throw new Exception("Invalid index!");
		}

		this.tmpIndexTS = doIncreaseIndex(index, tmpIndexTS);
		queProp.setProperty(tapScr + tmpIndexTS, ts);

		return this.tmpIndexTS;
	}

	/**
	 * Invoking: this.indexType = doIncreaseIndex(index, indexType);
	 * 
	 * @param index
	 *            must be greater than 0 and smaller than amount of question
	 * @param indexType
	 *            is one of three types: indexTS, indexAN, or indexQU
	 * @return increase an element if index == indexType else index itself
	 */
	protected int doIncreaseIndex(int index, int indexType) {
		if (index == indexType) {
			if (indexType < amtQue) {
				indexType++;
			}
		} else {
			indexType = index;
		}

		return indexType;
	}

	protected boolean checkValidIndex(int index) {
		if (index < 1 || index > amtQue) {
			return false;
		}

		return true;
	}

	protected void writeHeader(String pathFileMp3) throws Exception {
		if (pathFileMp3 != null) {
			queProp.setProperty(this.pathFileMp3, pathFileMp3);
			this.enalbe = true;
		} else {
			this.enalbe = false;
			throw new Exception("path file mp3 is null");
		}
	}

	public int writeCorrectAnswers(String[] correctAnswers, int index) {
		int num = correctAnswers.length;
		if (num == amtQue) { // add multiple
			for (int i = 0; i < num; i++) {
				// get first letter
				char[] tmpChars = correctAnswers[i].toCharArray();
				for (char s : tmpChars) {
					if (Character.isAlphabetic(s)) {
						queProp.setProperty(questionStr + String.valueOf(i + 1)
								+ answerStr, String.valueOf(s));
						break;
					}
				}
			}
			this.enalbe = true;
		} else if (num == 1) { // add single
			if (checkValidIndex(index)) {
				this.tmpIndexAN = doIncreaseIndex(index, tmpIndexAN);
				queProp.setProperty(questionStr + String.valueOf(tmpIndexAN)
						+ answerStr,
						String.valueOf(correctAnswers[0].charAt(0)));
			}
		} else {
			this.enalbe = false;
		}

		if (!enalbe) {
			JOptionPane.showMessageDialog(comp,
					"Amount of Answer do not match amount of Question!");
		}

		return tmpIndexAN;
	}

	public int writeQueAns(int index) throws Exception {
		if (questionVal == null) {
			throw new Exception("questionVal is not set!");
		}
		if (answersVal == null) {
			throw new Exception("answersVal is not set!");
		}

		if ((index < 1 && index != -1) || index > amtQue) {
			throw new Exception("Index is not valid!");
		} else if (index == amtQue || index == -1) {
			writeAmtQue(++amtQue);
			if (index == -1) {
				this.tmpIndexQU = 0;
				index = amtQue;
			}
		}

		this.tmpIndexQU = doIncreaseIndex(index, tmpIndexQU);
		writeQuestion(tmpIndexQU, questionVal, answersVal);
		questionVal = null;
		answersVal = null;

		// update field amount of question
		comp.updateAfterInsertAQuestion(tmpIndexQU);
		return tmpIndexQU;
	}

	protected void writeAmtQue(int amtOfQue) {
		queProp.setProperty(amountOfQuestion, String.valueOf(amtOfQue));
	}

	protected void writeQuestion(int num, String question, String[] answers) {
		String strTmp = questionStr + String.valueOf(num);
		// question
		queProp.setProperty(strTmp, question);
		// answers
		for (int i = 0; i < 4; i++) {
			queProp.setProperty(strTmp + String.valueOf(ansLetStr.charAt(i)),
					answers[i]);
		}
	}

	public String formatQuestion(String[] texts) {
		StringBuffer strBuffer = new StringBuffer();
		if (texts == null || texts.length < 1) {
			return null;
		}

		for (String s : texts) {
			if (s != null && s.length() > 0) {
				// Remove the blank at first
				while(s.charAt(0) == ' ') {
					s = s.substring(1);
				}
				strBuffer.append(s + "\n");
			}
		}

		return strBuffer.toString();
	}

	public String formatAnswer(String[] texts) {
		StringBuffer strBuffer = new StringBuffer();
		String tmpStr;
		final String standardLetter = "ABCD";
		char[] tmpChars = null;
		int num = 0;
		for (String str : texts) {
			// check beginning of line: if is not a letter
			tmpStr = str.trim(); // remove all blank space
			if (tmpStr == null || tmpStr.length() < 1) {
				continue; // ignore the blank line
			}
			if (Character.isAlphabetic(str.charAt(0))) {
				// check first char only
				continue; // ignore this line
			}
			// get The capital letter of Answer
			tmpChars = tmpStr.toCharArray();
			for (char s : tmpChars) {
				if (standardLetter.contains(String.valueOf(s))) {
					// rewrite the result to new format
					num++;
					strBuffer.append(String.valueOf(num) + " "
							+ String.valueOf(s) + "\t" + str + "\n");
					break; // only get first letter
				}
			}
		}
		return strBuffer.toString();
	}

	public void setSaveToPath(String saveToPath) {
		this.saveToPath = saveToPath;
	}

	public int getAmtQue() {
		return amtQue;
	}

	public void setEnalbe(boolean enalbe) {
		this.enalbe = enalbe;
	}

	public boolean isEnalbe() {
		return enalbe;
	}

	public void setQueProp(Properties queProp) {
		this.queProp = queProp;
	}

}
